import math
import os
import time

from common import get_audio_temp_dir
from log_manager import LogManager
from python_get_resolve import GetResolve


def get_file_base_name(project, timeline):
    return project.GetName() + "_" + timeline.GetName()


def clear_render_queue(project):
    """
    清理渲染队列中的音频渲染任务
    :param project: DaVinci Resolve项目对象
    """
    # 获取所有渲染任务
    render_jobs = project.GetRenderJobList()
    if not render_jobs:
        return

    LogManager.log(f"当前渲染队列任务数: {len(render_jobs)}")

    # 获取当前时间线名称作为比较
    base_name = get_file_base_name(project, project.GetCurrentTimeline())
    LogManager.log(f"当前音频文件基础名称: {base_name}")

    # 获取temp目录的标准化路径
    temp_path = get_audio_temp_dir().rstrip("/")  # 移除末尾的斜杠
    LogManager.log(f"Temp目录路径: {temp_path}")

    # 遍历并只删除音频渲染任务
    for job in render_jobs:
        job_id = job.get("JobId")
        job_name = job.get("RenderJobName")
        target_dir = (job.get("TargetDir") or "").rstrip("/")  # 移除末尾的斜杠
        custom_name = job.get("CustomName")

        LogManager.log("检查渲染任务:")
        LogManager.log(f"- ID: {job_id}")
        LogManager.log(f"- 名称: {job_name}")
        LogManager.log(f"- 目标目录: {target_dir}")
        LogManager.log(f"- 自定义名称: {custom_name}")

        # 检查是否是我们生成的音频任务
        if job_id and target_dir:
            # 标准化路径后比较
            if target_dir == temp_path:
                LogManager.log(f"找到匹配的音频渲染任务: {job_id}")
                success = project.DeleteRenderJob(job_id)
                if success:
                    LogManager.log("删除音频渲染任务成功")
                else:
                    LogManager.log("删除音频渲染任务失败")
            else:
                LogManager.log("目标目录不匹配")
                LogManager.log(f"期望路径: {temp_path}")
                LogManager.log(f"实际路径: {target_dir}")
        else:
            LogManager.log("任务ID或目标目录为空")


def render_audio(resolve, project, timeline):
    # 清理渲染队列
    clear_render_queue(project)

    # 使用新的文件名格式
    base_name = get_file_base_name(project, timeline)

    # 切换到编辑页面
    resolve.OpenPage("edit")

    # 获取帧率
    frame_rate = timeline.GetSetting()["timelineFrameRate"]

    # 设置渲染参数
    project.LoadRenderPreset("Audio Only")
    project.SetRenderSettings(
        {
            "SelectAllFrames": 1,
            "CustomName": base_name,
            "TargetDir": get_audio_temp_dir(),
            "AudioCodec": "Linear PCM",
            "ExportVideo": False,
            "ExportAudio": True,
            "AudioBitDepth": "16",
            "AudioSampleRate": "48000",
            "FileExtension": "wav",
        }
    )

    # 添加渲染任务
    job_id = project.AddRenderJob()
    if not job_id:
        print("错误: 添加渲染任务失败")
        return None

    # 开始渲染
    print("开始渲染...")
    if not project.StartRendering(job_id):
        print("错误: 启动渲染失败")
        return None

    LogManager.log("正在渲染音频...")

    # 等待渲染完成
    start_time = time.time()
    timeout = 300  # 5分钟超时
    location = os.path.join(get_audio_temp_dir(), base_name + ".wav")
    last_status = ""
    no_progress_count = 0

    while True:
        # 检查超时
        if time.time() - start_time > timeout:
            LogManager.log("渲染超时")
            return None

        # 检查渲染状态
        job_status = project.GetRenderJobStatus(job_id)
        if not job_status:
            LogManager.log("等待渲染状态...")
            time.sleep(1.0)
            no_progress_count += 1
            if no_progress_count > 30:  # 30秒无响应
                LogManager.log("渲染似乎卡住了，尝试重新开始...")
                project.StartRendering(job_id)
                no_progress_count = 0
            continue

        # 重置无进度计数器
        no_progress_count = 0

        # 检查渲染状态变化
        current_status = job_status["JobStatus"] or ""
        if current_status != last_status:
            LogManager.log(f"渲染状态: {current_status}")
            last_status = current_status

        # 检查渲染是否完成
        if current_status == "Complete" or current_status == "完成":  # 添加中文状态检查
            LogManager.log("渲染任务完成，等待文件写入...")
            # 等待文件写入完成
            time.sleep(2.0)

            # 检查文件是否存在且可以打开
            if os.path.exists(location):
                LogManager.log(f"音频文件生成成功: {location}")
                # 确保退出循环
                return location, None, frame_rate
        elif current_status == "Failed" or current_status == "失败":  # 添加中文状态检查
            LogManager.log("渲染失败!")
            return None

        # 显示进度
        if (
            job_status.get("CompletedFrames")
            and job_status.get("TotalFrames")
            and job_status.get("TotalFrames") > 0
        ):
            progress = math.floor(
                (job_status.get("CompletedFrames") / job_status.get("TotalFrames"))
                * 100
            )
            if progress > 100:
                progress = 100
            LogManager.log(
                f"渲染进度: {progress}%"
                f" ({job_status.get('CompletedFrames')}/"
                f"{job_status.get('TotalFrames')})"
            )

        # 等待一段时间再检查
        time.sleep(1.0)


def do_render_resolve_audio():
    resolve = GetResolve()
    projectManager = resolve.GetProjectManager()
    # 获取当前打开的项目
    currentProject = projectManager.GetCurrentProject()
    # 输出项目名称
    LogManager.log(f"当前项目: {currentProject.GetName()}")
    # 获取当前打开的时间线

    currentTimeline = currentProject.GetCurrentTimeline()
    LogManager.log(f"当前时间线: {currentTimeline.GetName()}")
    audio_path, _, _ = render_audio(resolve, currentProject, currentTimeline)
    LogManager.log(f"音频文件: {audio_path}")
    return audio_path, currentProject.GetName(), currentTimeline.GetName()


def append_srt_to_timeline(srt_path):
    """将SRT字幕文件添加到时间线中
    Args:
        srt_path: SRT文件路径
    Returns:
        bool: 是否成功添加字幕
    """
    resolve = GetResolve()
    projectManager = resolve.GetProjectManager()
    # 获取当前打开的项目
    currentProject = projectManager.GetCurrentProject()
    # 获取媒体池
    media_pool = currentProject.GetMediaPool()
    if not media_pool:
        LogManager.log("错误: 无法获取媒体池")
        return False

    # 确保在根文件夹中
    root_folder = media_pool.GetRootFolder()
    media_pool.SetCurrentFolder(root_folder)

    # 获取文件名（不包含路径）
    import os

    srt_filename = os.path.basename(srt_path)
    LogManager.log(f"检查媒体池中是否存在: {srt_filename}")

    # 检查媒体池中是否已存在该SRT文件
    existing_items = root_folder.GetClipList()
    for item in existing_items:
        clip_name = item.GetName()
        if clip_name == srt_filename:
            LogManager.log(f"在媒体池中找到已存在的字幕文件: {clip_name}")
            # 删除已存在的字幕文件
            media_pool.DeleteClips([item])
            LogManager.log(f"已从媒体池中删除: {clip_name}")
            break

    # 导入SRT文件
    media_pool_items = media_pool.ImportMedia(srt_path)
    if not media_pool_items:
        LogManager.log("错误: 导入字幕文件失败")
        return False

    media_pool_item = media_pool_items[0]
    LogManager.log("成功: 字幕文件已导入到媒体池")

    # 将字幕添加到时间线
    success = media_pool.AppendToTimeline([media_pool_item])
    if not success:
        LogManager.log("错误: 将字幕添加到时间线失败")
        return False

    LogManager.log("成功: 字幕已添加到时间线")
    return True


if __name__ == "__main__":
    srt_file, _, _ = do_render_resolve_audio()
    append_srt_to_timeline(srt_file)
